package org.demo.db.xsd;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;

/**
 * 测试类
 * @author  
 * @date    2010-8-30
 * @file    org.gen.test.Main.java
 */
public class Main {

	/**
	 * 测试
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		Main t = new Main();
		t.init();
	}
	// 主窗口
	private JFrame mainWin;
	private int width = 600;
	private int height = 400;
	private Insets insets = new Insets(0,0,0,0);
	private Font font = new Font("宋体", Font.BOLD, 14);
	// 
	private JTextField txtCfg;
	private JButton btnSelect;
	private JList listJars;
	private JButton btnAdd;
	private JButton btnDel;
	private JButton btnExe;
	private JTextArea message = new JTextArea();
	private BtnListener btnListener = new BtnListener();
	// 
	private Set<String> setJars = new HashSet<String>();
	private ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
	
	/**
	 * 构造函数
	 */
	public Main(){
		// 重定向输出流
		PrintStream sysout = new PrintStream(out);
		System.setOut(sysout);
	}
	/**
	 * 初始化
	 */
	public void init(){
		UIManager.put("Label.font", font);
		UIManager.put("Button.font", font);
		UIManager.put("TextField", font);
		
		JFrame.setDefaultLookAndFeelDecorated(true);
		mainWin = new JFrame();
		// 
		Toolkit kit = Toolkit.getDefaultToolkit();
		Dimension screen = kit.getScreenSize();
		int left = (screen.width - width)/2;
		int top = (screen.height - height)/2;
		// 
		mainWin.setTitle("Xsd生成工具");
		mainWin.setSize(width,height);
		mainWin.setLocation(left,top);
		mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 
		mainWin.setLayout(new BorderLayout());
		mainWin.add(createTop(), BorderLayout.NORTH);
		mainWin.add(createCenter(),BorderLayout.CENTER);
		mainWin.add(createBottom(),BorderLayout.SOUTH);
		// 
		mainWin.setVisible(true);
	}
	/**
	 * 创建 top 区域组件
	 * @return
	 */
	private JPanel createTop(){
		JLabel labSel = new JLabel("请选择配置文件：");
		txtCfg = new JTextField("");
		btnSelect = new JButton("选择...");
		// top panel
		JPanel pTop = new JPanel();
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints cons = new GridBagConstraints();
		pTop.setLayout(gridbag);
		
		cons.fill = GridBagConstraints.HORIZONTAL;
		cons.gridx = 0;
		cons.gridy = 0;
		gridbag.setConstraints(labSel, cons);
		pTop.add(labSel);
		
		cons.gridx = 1;
		cons.gridwidth = GridBagConstraints.RELATIVE;
		cons.weightx = 0.9;
		gridbag.setConstraints(txtCfg,cons);
		pTop.add(txtCfg);
		
		cons.gridx = 2;
		cons.weightx = 0.1;
		btnSelect.setMargin(insets);
		btnSelect.setActionCommand("selectXml");
		btnSelect.addActionListener(btnListener);
		gridbag.setConstraints(btnSelect, cons);
		pTop.add(btnSelect);
		
		return pTop;
	}
	/**
	 * 创建 center 区域组件
	 * @return
	 */
	private JPanel createCenter(){
		JLabel labDriver = new JLabel("JDBC Driver:");
		listJars = new JList();
		btnAdd = new JButton("Add Jars...");
		btnDel = new JButton("Remove");
		btnExe = new JButton("Execute");
		listJars.setModel(new DefaultListModel());
		JScrollPane scroll = new JScrollPane(listJars);
		
		JPanel pCenter = new JPanel();
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints cons = new GridBagConstraints();
		pCenter.setLayout(gridbag);
		
		cons.fill = GridBagConstraints.BOTH;
		cons.gridx = 0;
		cons.gridy = 0;
		cons.gridwidth = 3;
		gridbag.setConstraints(labDriver, cons);
		pCenter.add(labDriver);
		
		cons.gridx = 0;
		cons.gridy = 1;
		cons.gridwidth = 2;
		cons.gridheight = 3;
		cons.weightx = 0.9;
		cons.weighty = 1.0;
		gridbag.setConstraints(scroll, cons);
		pCenter.add(scroll);
		
		cons.gridx = 2;
		cons.gridy = 1;
		cons.gridwidth = 1;
		cons.gridheight = 1;
		cons.weightx = 0.1;
		cons.weighty = 0.2;
		btnAdd.setMargin(insets);
		btnAdd.setActionCommand("addJars");
		btnAdd.addActionListener(btnListener);
		gridbag.setConstraints(btnAdd, cons);
		pCenter.add(btnAdd);
		
		cons.gridy = 2;
		btnDel.setMargin(insets);
		btnDel.setActionCommand("delJars");
		btnDel.addActionListener(btnListener);
		gridbag.setConstraints(btnDel, cons);
		pCenter.add(btnDel);
		
		cons.gridy = 3;
		btnExe.setMargin(insets);
		btnExe.setActionCommand("exeGen");
		btnExe.addActionListener(btnListener);
		gridbag.setConstraints(btnExe, cons);
		pCenter.add(btnExe);
		
		return pCenter;
	}
	/**
	 * 创建 bottom 区域组件
	 * @return
	 */
	private Component createBottom(){
		message = new JTextArea("");
		message.setPreferredSize(new Dimension(1,60));
		JScrollPane scroll = new JScrollPane(message);
		return scroll;
	}
	/**
	 * 按钮动作监听
	 * @author 
	 *
	 */
	class BtnListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			String cmd = e.getActionCommand();
			try {
				Method method = Main.class.getMethod(cmd);
				method.invoke(Main.this, new Object[]{});
			} catch (Exception cep) {
				cep.printStackTrace();
			}
		}
	}
	/**
	 * 选择 xml 配置文件
	 */
	public void selectXml(){
		JFileChooser chooser = new JFileChooser();
		String dir = System.getProperty("user.dir");
		chooser.setCurrentDirectory(new File(dir));
		chooser.setFileFilter(new FileFilter() {
			@Override
			public String getDescription() {
				return "*.xml";
			}
			
			@Override
			public boolean accept(File f) {
				if (f.isFile() && !f.getName().endsWith(".xml")){
					return false;
				}
				return true;
			}
		});
		int result = chooser.showOpenDialog(this.mainWin);
		if (result == JFileChooser.APPROVE_OPTION){
			File file = chooser.getSelectedFile();
			txtCfg.setText(file.getAbsolutePath());
		}
	}
	/**
	 * 添加 jar
	 */
	public void addJars(){
		JFileChooser chooser = new JFileChooser();
		String dir = System.getProperty("user.dir");
		chooser.setCurrentDirectory(new File(dir));
		chooser.setMultiSelectionEnabled(true);
		chooser.setFileFilter(new FileFilter() {
			@Override
			public String getDescription() {
				return "*.jar";
			}
			
			@Override
			public boolean accept(File f) {
				if (f.isFile() && !f.getName().endsWith(".jar")){
					return false;
				}
				return true;
			}
		});
		int result = chooser.showOpenDialog(this.mainWin);
		if (result == JFileChooser.APPROVE_OPTION){
			File[] files = chooser.getSelectedFiles();
			DefaultListModel model = (DefaultListModel)listJars.getModel();
			for (int i=0; i<files.length; i++){
				String filename = files[i].getAbsolutePath();
				if (!setJars.contains(filename)){
					setJars.add(filename);
					model.addElement(filename);
				}
			}
		}
	}
	/**
	 * 删除 jar
	 */
	public void delJars(){
		DefaultListModel model = (DefaultListModel)listJars.getModel();
		Object[] vals = listJars.getSelectedValues();
		for(int i=0;i<vals.length;i++){
			setJars.remove(vals[i]);
			model.removeElement(vals[i]);
		}
	}
	/**
	 * 执行 xsd 生成工具
	 */
	public void exeGen(){
		String filename = txtCfg.getText().trim();
		if (filename.equals("")){
			System.out.println("请选择配置文件！");
			refreshMessage();
			return;
		}
		DefaultListModel model = (DefaultListModel)listJars.getModel();
		Enumeration<?> vals = model.elements();
		List<URL> list = new ArrayList<URL>();
		while(vals.hasMoreElements()){
			String val = (String)vals.nextElement();
			File file = new File(val);
			try {
				URL url = file.toURI().toURL();
				list.add(url);
			} catch (Exception e){
				e.printStackTrace();
			}
		}
		URL[] urls = list.toArray(new URL[list.size()]);
		// 自动生成 xsd
		String dir = System.getProperty("user.dir");
		DbClassLoader dloader = new DbClassLoader(dir);
		dloader.addUrls(urls);
		try {
			XsdGenerator gen = new XsdGenerator();
			gen.setDriverLoader(dloader);
			gen.generate(filename);
			System.out.println("-- ok. --");
		} catch (Exception e){
			e.printStackTrace();
		}
		refreshMessage();
	}
	/**
	 * 涮新消息
	 */
	private void refreshMessage(){
		message.setText(out.toString());
		out.reset();
	}
}
